/*
 * SHOPTNT 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.shoptnt.cn
 */
package cn.shoptnt.api.manager.system;


import cn.shoptnt.client.system.SmsClient;
import cn.shoptnt.framework.ShopTntConfig;
import cn.shoptnt.framework.cache.Cache;
import cn.shoptnt.framework.context.user.AdminUserContext;
import cn.shoptnt.framework.exception.ServiceException;
import cn.shoptnt.framework.security.model.Admin;
import cn.shoptnt.framework.util.StringUtil;
import cn.shoptnt.framework.util.Validator;
import cn.shoptnt.model.base.CachePrefix;
import cn.shoptnt.model.base.SceneType;
import cn.shoptnt.model.errorcode.MemberErrorCode;
import cn.shoptnt.model.system.dos.AuthenticationDO;
import cn.shoptnt.service.system.SecondaryAuthenticationManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;

/**
 * 安全相关API
 * 二次验证相关
 * 此API所有管理员都可以访问
 *
 * @author snow
 * 2021年11月20日17:15:24
 */
@Api(tags= "安全相关API")
@RestController
@RequestMapping("/admin/passport")
@Validated
public class PassportManagerController {

    @Autowired
    private ShopTntConfig shoptntConfig;

    @Autowired
    private SecondaryAuthenticationManager secondaryAuthenticationManager;

    @Autowired
    private SmsClient smsClient;

    @Autowired
    private Cache cache;

    /**
     * 二次身份验证-获取验证码
     *
     * @return
     */
    @PostMapping(value = "/sms-code")
    @ApiOperation(value = "二次身份验证-获取验证码")
    public String sendSmsCode() {
        //读取用户ID
        Long userId = AdminUserContext.getAdmin().getUid();
        AuthenticationDO authenticationDO = this.secondaryAuthenticationManager.getModelByUid(userId);
        if (authenticationDO == null) {
            throw new ServiceException("500", "请先设置安全配置");
        }
        String mobile = authenticationDO.getMobile();
        //发送验证码
        if (!Validator.isMobile(mobile)) {
            throw new ServiceException(MemberErrorCode.E107.code(), "手机号码格式不正确！");
        }
        //发送验证码短信
        smsClient.sendSmsMessage("登录", mobile, SceneType.SET_PAY_PWD);


        return shoptntConfig.getSmscodeTimout() / 60 + "";
    }

    /**
     * 二次身份验证-验证手机验证码
     *
     * @return
     */
    @PostMapping(value = "/check-sms-code")
    @ApiOperation(value = "二次身份验证-验证手机验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "scene", value = "业务类型", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query"),
            @ApiImplicitParam(name = "sms_code", value = "验证码", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query"),
    })
    public String checkSmsCode(@NotEmpty(message = "业务场景不能为空") String scene,
                               @Valid @ApiIgnore @NotEmpty(message = "验证码不能为空") String smsCode) {
        //读取用户ID
        Long userId = AdminUserContext.getAdmin().getUid();
        AuthenticationDO authenticationDO = this.secondaryAuthenticationManager.getModelByUid(userId);
        if (authenticationDO == null) {
            throw new ServiceException("500", "请先设置安全配置");
        }
        String mobile = authenticationDO.getMobile();

        //验证短信二维码
        boolean isPass = smsClient.valid(scene, mobile, smsCode);
        if (!isPass) {
            throw new ServiceException(MemberErrorCode.E107.code(), "短信验证码不正确");
        }
        this.cache.put(CachePrefix.TWO_STEP_FLAG.getPrefix() + userId, "SUCCESS");
        return "YES";
    }


    /**
     * 二次身份验证-验证密码
     *
     * @return
     */
    @PostMapping(value = "/check-password")
    @ApiOperation(value = "二次身份验证-验证密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query"),
    })
    public String checkPassword(@NotEmpty(message = "密码不能为空") String password) {
        //读取用户ID
        Admin admin = AdminUserContext.getAdmin();

        AuthenticationDO authenticationDO = this.secondaryAuthenticationManager.getModelByUid(admin.getUid());
        if (authenticationDO == null) {
            throw new ServiceException("500", "请先设置安全配置");
        }
        //读取配置的密码
        String mysqlPassword = authenticationDO.getPassword();
        String md5Password = StringUtil.md5(password + admin.getUsername().toLowerCase());
        //判断密码是否匹配
        if (!mysqlPassword.equals(md5Password)) {
            throw new ServiceException(MemberErrorCode.E107.code(), "密码不正确");
        }
        this.cache.put(CachePrefix.TWO_STEP_FLAG.getPrefix() + admin.getUid(), "SUCCESS");
        return "YES";
    }


    @GetMapping("/two-step-set")
    @ApiOperation(value = "查询一个二次身份验证配置信息")
    public AuthenticationDO get() {
        AuthenticationDO authentication = this.secondaryAuthenticationManager.getModelByUid(AdminUserContext.getAdmin().getUid());
        return authentication;
    }


}
